import { INVALID_VALUE } from './../../../Core/CoreDefine';
import { ObjectWrap } from './../../../Core/FrameEx/ES5Ex';
import JXRBCmdMgr from "./JXRBCmdMgr";
import { JXRBRole } from "./JXRBRole";
import { COMMON_ANI_NAME, JXBattleBuffRoot, JXBuffOrderThreshold, JXEDir, JXEState, JXRB_ROLE_LAYER_NAME } from './JXULDefine';



export class JXRBBuff extends ObjectWrap {
    protected _effectRaw: SEffectAnimRaw;
    /** 效果在技能表中的索引 */
    public index: number;
    public skillId: number;
    public execer: JXRBRole;
    /** 当前存在的BUFF实例 */
    public buffuuids: string[];

    public layerOrder: number;

    public buffFrames: cc.Node[] = [];

    protected _active: boolean = true;

    protected _cmd: JXRBCmdMgr = null;

    public get visLayer(): number[] {
        return this._effectRaw.visFirst;
    }

    public get effectFirst(): number {
        return this._effectRaw.effectFirst;
    }

    public get ext() {
        return this._effectRaw.ext;
    }

    public get offset(): cc.Vec2[] {
        let offsets = []
        for (let i = 0; i < this._effectRaw.effect.length; i++) {
            let curOffset = this._effectRaw.position[i];
            if (curOffset) offsets.push(cc.v2(curOffset[0], curOffset[1]));
            else offsets.push(cc.Vec2.ZERO);
        }
        return offsets;
    }

    public get state(): JXEState {
        return this._effectRaw.state;
    }

    constructor(skillId: number, index: number, effectRaw: any, cmd: JXRBCmdMgr) {
        super();
        this.index = index;
        this.buffuuids = [];
        this.skillId = skillId;
        this._effectRaw = effectRaw;
        this._cmd = cmd;
    }

    public addToTarget(role: JXRBRole) {
        this.execer = role;
        let visiLayer = this.visLayer;
        let offsets = this.offset;
        for (let i = 0; i < this._effectRaw.effect.length; i++) {
            let animation = this._cmd.assetManager.createEffect(this._effectRaw.effect[i] as any, JXBattleBuffRoot, cc.WrapMode.Loop);
            if (visiLayer[i] < JXBuffOrderThreshold) {
                let layer = role.target.getChildByName(JXRB_ROLE_LAYER_NAME.LOWER);
                animation.node.parent = layer;
            }
            else {
                let layer = role.target.getChildByName(JXRB_ROLE_LAYER_NAME.UPPER);
                animation.node.parent = layer;
            }
            let dir = (role.dir == JXEDir.Right ? 1 : -1);
            animation.node.zIndex = this.visLayer[i];
            offsets[i].x *= dir;
            animation.node.position = offsets[i];
            animation.node.scaleX *= dir;
            animation.play(COMMON_ANI_NAME);
            this.buffFrames.push(animation.node);
        }
    }

    public addInsBuff(uuid: string) {
        let index = this.buffuuids.indexOf(uuid);
        if (index != INVALID_VALUE) return;
        this.buffuuids.push(uuid);
    }

    public removeInsBuff(uuid: string) {
        let index = this.buffuuids.indexOf(uuid);
        if (index == INVALID_VALUE) return;
        this.buffuuids.splice(index, 1);
        if (this.buffuuids.length == 0) {
            this.execer.removeBuff(this);
        }
    }

    public hasInsBuff(uuid: string): boolean {
        return this.buffuuids.indexOf(uuid) != INVALID_VALUE;
    }

    public destroy() {
        this.execer.btlActionMgr.removeAllActionsFromTarget(this, true);
        this._effectRaw = null;
        this.execer = null;
        for (let i = 0; i < this.buffFrames.length; i++) {
            this.buffFrames[i].destroy();
        }
        this.buffFrames.length = 0;
        this.buffuuids = [];
        this._cmd = null;
    }

    public set active(val: boolean) {
        this._active = val;
        this.buffFrames.forEach(frame => {
            frame.active = val;
        })
    }

    public get active(): boolean {
        return this._active;
    }

}